package com.ruoyi.business.service.wecom.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.ruoyi.business.domain.fission.TbWecomChatGroupFission;
import com.ruoyi.business.domain.fission.TbWecomChatGroupFissionInvite;
import com.ruoyi.business.domain.wecom.*;
import com.ruoyi.business.mapper.wecom.TbWecomCallbackMsgInfoMapper;
import com.ruoyi.business.service.fission.ITbWecomChatGroupFissionInviteService;
import com.ruoyi.business.service.fission.ITbWecomChatGroupFissionService;
import com.ruoyi.business.service.wecom.*;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.enums.fission.GroupFissionInviteStatusEnum;
import com.ruoyi.common.enums.fission.GroupFissionStatusEnum;
import com.ruoyi.common.enums.wecom.*;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.cp.api.WxCpExternalContactService;
import me.chanjar.weixin.cp.api.WxCpService;
import me.chanjar.weixin.cp.bean.external.WxCpUserExternalGroupChatInfo;
import me.chanjar.weixin.cp.bean.external.WxCpUserExternalTagGroupList;
import me.chanjar.weixin.cp.bean.external.contact.ExternalContact;
import me.chanjar.weixin.cp.bean.external.contact.FollowedUser;
import me.chanjar.weixin.cp.bean.external.contact.WxCpExternalContactInfo;
import me.chanjar.weixin.cp.bean.message.WxCpXmlMessage;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

@Service
@Slf4j
public class TbWecomCallbackMsgInfoServiceImpl extends ServiceImpl<TbWecomCallbackMsgInfoMapper, TbWecomCallbackMsgInfo> implements ITbWecomCallbackMsgInfoService {

    @Resource
    private WxCpService wxCpService;

    @Resource
    private ITbWecomChatGroupService wecomChatGroupService;

    @Resource
    private ITbWecomChatGroupMemberService wecomChatGroupMemberService;

    @Resource
    private ITbWecomTagGroupService tbWecomTagGroupService;

    @Resource
    private ITbWecomTagService tbWecomTagService;

    @Resource
    private ITbWecomExternalContactCustomerService tbWecomExternalContactCustomerService;

    @Resource
    private ITbWecomExternalContactCustomerFollowUserService tbWecomExternalContactCustomerFollowUserService;

    @Resource
    private ITbWecomExternalContactCustomerFollowUserTagService tbWecomExternalContactCustomerFollowUserTagService;

    @Resource
    private ITbWecomChatGroupFissionInviteService tbWecomChatGroupFissionInviteService;

    @Resource
    private ITbWecomChatGroupFissionService tbWecomChatGroupFissionService;

    private final Gson gson = new Gson();


    /**
     * 创建群聊消息回调处理
     *
     * @param message
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void groupCreatEventHandler(WxCpXmlMessage message) {
        // 保存回调信息记录
        TbWecomCallbackMsgInfo tbWecomCallbackMsgInfo = new TbWecomCallbackMsgInfo();
        tbWecomCallbackMsgInfo.setId(IdWorker.getId());
        tbWecomCallbackMsgInfo.setAgentId(message.getAgentId());
        tbWecomCallbackMsgInfo.setToUserName(message.getToUserName());
        tbWecomCallbackMsgInfo.setFromUserName(message.getFromUserName());
        tbWecomCallbackMsgInfo.setMsgCreateTime(message.getCreateTime());
        tbWecomCallbackMsgInfo.setMsgType(message.getMsgType());
        tbWecomCallbackMsgInfo.setEvent(message.getEvent());
        tbWecomCallbackMsgInfo.setChatId(message.getChatId());
        tbWecomCallbackMsgInfo.setChangeType(message.getChangeType());
        tbWecomCallbackMsgInfo.setFullMsg(gson.toJson(message));
        tbWecomCallbackMsgInfo.setCreateTime(new Date());
        this.save(tbWecomCallbackMsgInfo);
        // 获取群详情
        WxCpExternalContactService externalContactService = wxCpService.getExternalContactService();
        WxCpUserExternalGroupChatInfo groupChat;
        try {
            groupChat = externalContactService.getGroupChat(message.getChatId(), Constants.TRUE_1);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        // 插入数据
        List<TbWecomChatGroupMember> wecomChatGroupMemberList = new ArrayList<>();
        groupChat.getGroupChat().getMemberList().forEach(member -> {
            TbWecomChatGroupMember tbWecomChatGroupMember = new TbWecomChatGroupMember();
            tbWecomChatGroupMember.setId(IdWorker.getId());
            tbWecomChatGroupMember.setChatId(message.getChatId());
            tbWecomChatGroupMember.setUserId(member.getUserId());
            tbWecomChatGroupMember.setUserType(member.getType());
            tbWecomChatGroupMember.setUserUnionid(member.getUnionId());
            tbWecomChatGroupMember.setJoinTime(member.getJoinTime());
            tbWecomChatGroupMember.setJoinScene(member.getJoinScene());
            tbWecomChatGroupMember.setInvitorUserIds(member.getInvitor().getUserId());
            tbWecomChatGroupMember.setGroupNickname(member.getGroupNickname());
            tbWecomChatGroupMember.setName(StringUtils.isNotEmpty(member.getName()) ? member.getName() : StrUtil.EMPTY);
            tbWecomChatGroupMember.setState(StringUtils.isNotEmpty(member.getState()) ? member.getState() : StrUtil.EMPTY);
            tbWecomChatGroupMember.setCreateTime(new Date());
            wecomChatGroupMemberList.add(tbWecomChatGroupMember);
        });
        wecomChatGroupMemberService.saveBatch(wecomChatGroupMemberList);
        TbWecomChatGroup tbWecomChatGroup = new TbWecomChatGroup();
        tbWecomChatGroup.setId(IdWorker.getId());
        tbWecomChatGroup.setAgentId(message.getAgentId());
        tbWecomChatGroup.setChatId(message.getChatId());
        tbWecomChatGroup.setChatName(groupChat.getGroupChat().getName());
        tbWecomChatGroup.setChatNotice(groupChat.getGroupChat().getNotice());
        tbWecomChatGroup.setChatOwner(groupChat.getGroupChat().getOwner());
        tbWecomChatGroup.setMemberNum(wecomChatGroupMemberList.size());
        tbWecomChatGroup.setStatus(WecomChatGroupStatusEnum.NORMAL.getCode());
        tbWecomChatGroup.setAdminUserIds(groupChat.getGroupChat().getAdminList().stream().map(WxCpUserExternalGroupChatInfo.GroupAdmin::getUserId).collect(Collectors.joining(",")));
        tbWecomChatGroup.setMemberVersion(groupChat.getGroupChat().getMemberVersion());
        tbWecomChatGroup.setChatCreateTime(groupChat.getGroupChat().getCreateTime());
        wecomChatGroupService.save(tbWecomChatGroup);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void groupMemberAddEventHandler(WxCpXmlMessage message) {
        // 1. 添加空值检查
        if (ObjectUtil.isEmpty(message) || StringUtils.isBlank(message.getChatId())) {
            log.warn("群成员添加事件消息为空或聊天ID为空");
            return;
        }
        // 获取群详情
        WxCpExternalContactService externalContactService = wxCpService.getExternalContactService();
        WxCpUserExternalGroupChatInfo groupChat;
        try {
            groupChat = externalContactService.getGroupChat(message.getChatId(), Constants.TRUE_1);
        } catch (Exception e) {
            log.error("获取群聊详情失败, chatId: {}", message.getChatId(), e);
            throw new RuntimeException("获取群聊详情失败", e);
        }

        // 2. 检查群聊信息是否为空
        if (groupChat == null || groupChat.getGroupChat() == null) {
            log.warn("群聊信息为空, chatId: {}", message.getChatId());
            return;
        }

        // 更新群version
        TbWecomChatGroup tbWecomChatGroup = wecomChatGroupService.getOne(
            Wrappers.lambdaQuery(TbWecomChatGroup.class)
                .eq(TbWecomChatGroup::getChatId, message.getChatId())
        );

        // 3. 检查群组是否存在
        if (ObjectUtil.isEmpty(tbWecomChatGroup)) {
            log.warn("未找到对应的群组信息, chatId: {}", message.getChatId());
            return;
        }

        // 查询群详情
        tbWecomChatGroup.setMemberVersion(groupChat.getGroupChat().getMemberVersion());
        tbWecomChatGroup.setMemberNum(groupChat.getGroupChat().getMemberList().size());

        // 4. 安全处理管理员列表
        String adminUserIds = StrUtil.EMPTY;
        if (groupChat.getGroupChat().getAdminList() != null) {
            adminUserIds = groupChat.getGroupChat().getAdminList().stream()
                .filter(Objects::nonNull)
                .map(WxCpUserExternalGroupChatInfo.GroupAdmin::getUserId)
                .filter(Objects::nonNull)
                .collect(Collectors.joining(","));
        }
        tbWecomChatGroup.setAdminUserIds(adminUserIds);
        tbWecomChatGroup.setUpdateTime(new Date());
        wecomChatGroupService.updateById(tbWecomChatGroup);

        // 插入数据
        List<TbWecomChatGroupMember> wecomChatGroupMemberList = new ArrayList<>();
        // 过滤出目标用户 新增
        Object memChangeList = message.getAllFieldsMap().get("MemChangeList");
        Object lastMemVer = message.getAllFieldsMap().get("LastMemVer");
        Object curMemVer = message.getAllFieldsMap().get("CurMemVer");
        // 5. 安全处理变更用户列表
        List<String> changeUserIds = new ArrayList<>();
        if (ObjectUtil.isNotEmpty(memChangeList)) {
            try {
                JsonElement jsonElement = gson.toJsonTree(memChangeList);
                if (jsonElement.isJsonObject()) {
                    JsonObject jsonObject = jsonElement.getAsJsonObject();
                    JsonArray jsonArray = jsonObject.getAsJsonArray("Item");
                    if (ObjectUtil.isNotEmpty(jsonArray)) {
                        for (JsonElement element : jsonArray) {
                            if (ObjectUtil.isNotEmpty(element) && !element.isJsonNull()) {
                                changeUserIds.add(element.getAsString());
                            }
                        }
                    }
                }
            } catch (Exception e) {
                log.warn("解析MemChangeList失败", e);
            }
        }
        // 保存回调消息
        TbWecomCallbackMsgInfo tbWecomCallbackMsgInfoMemberAdd = new TbWecomCallbackMsgInfo();
        tbWecomCallbackMsgInfoMemberAdd.setId(IdWorker.getId());
        tbWecomCallbackMsgInfoMemberAdd.setAgentId(message.getAgentId());
        tbWecomCallbackMsgInfoMemberAdd.setToUserName(getSafeString(message.getToUserName()));
        tbWecomCallbackMsgInfoMemberAdd.setFromUserName(getSafeString(message.getFromUserName()));
        tbWecomCallbackMsgInfoMemberAdd.setMsgCreateTime(message.getCreateTime());
        tbWecomCallbackMsgInfoMemberAdd.setMsgType(getSafeString(message.getMsgType()));
        tbWecomCallbackMsgInfoMemberAdd.setUpdateDetail(getSafeString(message.getUpdateDetail()));
        tbWecomCallbackMsgInfoMemberAdd.setEvent(getSafeString(message.getEvent()));
        tbWecomCallbackMsgInfoMemberAdd.setChatId(getSafeString(message.getChatId()));
        tbWecomCallbackMsgInfoMemberAdd.setChangeType(getSafeString(message.getChangeType()));
        tbWecomCallbackMsgInfoMemberAdd.setUserId(String.join(",", changeUserIds));
        tbWecomCallbackMsgInfoMemberAdd.setJoinScene(getSafeString(message.getJoinScene()));

        // 10. 安全处理数值字段
        try {
            tbWecomCallbackMsgInfoMemberAdd.setMenChangeCnt(Integer.parseInt(getSafeString(message.getMemChangeCnt())));
        } catch (NumberFormatException e) {
            tbWecomCallbackMsgInfoMemberAdd.setMenChangeCnt(0);
        }
        tbWecomCallbackMsgInfoMemberAdd.setLastMemVer(getSafeString(String.valueOf(lastMemVer)));
        tbWecomCallbackMsgInfoMemberAdd.setCurMemVer(getSafeString(String.valueOf(curMemVer)));
        tbWecomCallbackMsgInfoMemberAdd.setFullMsg(gson.toJson(message));
        tbWecomCallbackMsgInfoMemberAdd.setCreateTime(new Date());
        this.save(tbWecomCallbackMsgInfoMemberAdd);

        // 6. 安全处理成员列表
        List<WxCpUserExternalGroupChatInfo.GroupMember> membersToProcess = new ArrayList<>();
        if (groupChat.getGroupChat().getMemberList() != null) {
            membersToProcess = groupChat.getGroupChat().getMemberList().stream()
                .filter(Objects::nonNull)
                .filter(member -> changeUserIds.contains(member.getUserId()))
                .collect(Collectors.toList());
        }
        // 7. 安全处理每个成员
        membersToProcess.forEach(groupMember -> {
            // 处理群裂变相关业务数据
            if (groupMember.getType() == WecomChatGroupUserTypeEnum.EXTERNAL_CONTACT.getCode()) {
                // 根据unionId 查询 群裂变邀请 信息
                TbWecomChatGroupFissionInvite tbWecomChatGroupFissionInvite = tbWecomChatGroupFissionInviteService.getOne(Wrappers.lambdaQuery(TbWecomChatGroupFissionInvite.class)
                    .eq(TbWecomChatGroupFissionInvite::getUserUnionId, groupMember.getUnionId())
                    .eq(TbWecomChatGroupFissionInvite::getStatus, GroupFissionInviteStatusEnum.NOT_JOINED.getCode())
                    .orderByDesc(TbWecomChatGroupFissionInvite::getCreateTime)
                    .last(Constants.MYBATIS_PLUSH_LIMIT_ONE));
                if (ObjectUtil.isNotEmpty(tbWecomChatGroupFissionInvite)) {
                    // qun裂变活动id
                    TbWecomChatGroupFission tbWecomChatGroupFission = tbWecomChatGroupFissionService.getById(tbWecomChatGroupFissionInvite.getFissionId());
                    if (Objects.equals(tbWecomChatGroupFission.getStatus(), GroupFissionStatusEnum.IN_PROGRESS.getCode())) {
                        tbWecomChatGroupFissionInvite.setStatus(GroupFissionInviteStatusEnum.JOINED.getCode());
                        tbWecomChatGroupFissionInvite.setUpdateTime(new Date());
                        tbWecomChatGroupFissionInvite.setChatId(message.getChatId());
                        tbWecomChatGroupFissionInviteService.updateById(tbWecomChatGroupFissionInvite);
                    }
                }
            }
            TbWecomChatGroup tbWecomChatGroupQuery = wecomChatGroupService.getOne(Wrappers.lambdaQuery(TbWecomChatGroup.class).eq(TbWecomChatGroup::getChatId, message.getChatId()));
            if (ObjectUtil.isNotEmpty(tbWecomChatGroupQuery)) {
                // 处理企微群 与 群成员
                try {
                    // 插入群成员
                    TbWecomChatGroupMember tbWecomChatGroupMember = new TbWecomChatGroupMember();
                    tbWecomChatGroupMember.setId(IdWorker.getId());
                    tbWecomChatGroupMember.setChatId(message.getChatId());
                    tbWecomChatGroupMember.setUserId(getSafeString(groupMember.getUserId()));
                    tbWecomChatGroupMember.setUserType(groupMember.getType());
                    tbWecomChatGroupMember.setUserUnionid(getSafeString(groupMember.getUnionId()));
                    tbWecomChatGroupMember.setJoinTime(groupMember.getJoinTime());
                    tbWecomChatGroupMember.setJoinScene(groupMember.getJoinScene());
                    // 8. 安全处理邀请人信息
                    if (groupMember.getInvitor() != null) {
                        tbWecomChatGroupMember.setInvitorUserIds(getSafeString(groupMember.getInvitor().getUserId()));
                    } else {
                        tbWecomChatGroupMember.setInvitorUserIds(StrUtil.EMPTY);
                    }
                    tbWecomChatGroupMember.setGroupNickname(getSafeString(groupMember.getGroupNickname()));
                    tbWecomChatGroupMember.setName(getSafeString(groupMember.getName()));
                    tbWecomChatGroupMember.setState(getSafeString(groupMember.getState()));
                    tbWecomChatGroupMember.setCreateTime(new Date());
                    wecomChatGroupMemberList.add(tbWecomChatGroupMember);
                } catch (Exception e) {
                    log.error("处理群成员信息失败, userId: {}", groupMember != null ? groupMember.getUserId() : "unknown", e);
                }
            }
        });
        // 9. 批量保存成员信息
        if (!wecomChatGroupMemberList.isEmpty()) {
            wecomChatGroupMemberService.saveBatch(wecomChatGroupMemberList);
        }

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void groupMemberDelEventHandler(WxCpXmlMessage message) {
        // 获取群详情
        WxCpExternalContactService externalContactService = wxCpService.getExternalContactService();
        WxCpUserExternalGroupChatInfo groupChat;
        try {
            groupChat = externalContactService.getGroupChat(message.getChatId(), Constants.TRUE_1);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        // 成员退群 群成员减少
        Object memChangeList = message.getAllFieldsMap().get("MemChangeList");
        Object lastMemVer = message.getAllFieldsMap().get("LastMemVer");
        Object curMemVer = message.getAllFieldsMap().get("CurMemVer");
        JsonElement jsonElement = gson.toJsonTree(memChangeList);
        JsonObject jsonObject = jsonElement.getAsJsonObject();
        JsonArray jsonArray = jsonObject.getAsJsonArray("Item");
        List<String> changeUserIds = new ArrayList<>();
        if (jsonArray != null) {
            for (JsonElement element : jsonArray) {
                // 直接获取字符串值，因为 Item 是字符串数组
                changeUserIds.add(element.getAsString());
            }
        }

        // 保存回调消息
        TbWecomCallbackMsgInfo tbWecomCallbackMsgInfoAdd = new TbWecomCallbackMsgInfo();
        tbWecomCallbackMsgInfoAdd.setId(IdWorker.getId());
        tbWecomCallbackMsgInfoAdd.setAgentId(message.getAgentId());
        tbWecomCallbackMsgInfoAdd.setToUserName(message.getToUserName());
        tbWecomCallbackMsgInfoAdd.setFromUserName(message.getFromUserName());
        tbWecomCallbackMsgInfoAdd.setMsgCreateTime(message.getCreateTime());
        tbWecomCallbackMsgInfoAdd.setMsgType(message.getMsgType());
        tbWecomCallbackMsgInfoAdd.setUpdateDetail(message.getUpdateDetail());
        tbWecomCallbackMsgInfoAdd.setEvent(message.getEvent());
        tbWecomCallbackMsgInfoAdd.setChatId(message.getChatId());
        tbWecomCallbackMsgInfoAdd.setChangeType(message.getChangeType());
        tbWecomCallbackMsgInfoAdd.setUserId(String.join(",", changeUserIds));
        tbWecomCallbackMsgInfoAdd.setJoinScene(message.getJoinScene());
        tbWecomCallbackMsgInfoAdd.setMenChangeCnt(Integer.valueOf(message.getMemChangeCnt()));
        tbWecomCallbackMsgInfoAdd.setLastMemVer(String.valueOf(lastMemVer));
        tbWecomCallbackMsgInfoAdd.setCurMemVer(String.valueOf(curMemVer));
        tbWecomCallbackMsgInfoAdd.setFullMsg(gson.toJson(message));
        tbWecomCallbackMsgInfoAdd.setCreateTime(new Date());
        this.save(tbWecomCallbackMsgInfoAdd);
        // 更新群信息
        TbWecomChatGroup tbWecomChatGroup = wecomChatGroupService.getOne(Wrappers.lambdaQuery(TbWecomChatGroup.class).eq(TbWecomChatGroup::getChatId, message.getChatId()));
        // 不存在 不做处理
        if (ObjectUtil.isNotEmpty(tbWecomChatGroup)) {
            // 查询群详情
            tbWecomChatGroup.setMemberVersion(groupChat.getGroupChat().getMemberVersion());
            tbWecomChatGroup.setMemberNum(groupChat.getGroupChat().getMemberList().size());
            tbWecomChatGroup.setAdminUserIds(groupChat.getGroupChat().getAdminList().stream().map(WxCpUserExternalGroupChatInfo.GroupAdmin::getUserId).collect(Collectors.joining(",")));
            tbWecomChatGroup.setUpdateTime(new Date());
            wecomChatGroupService.updateById(tbWecomChatGroup);

            List<WxCpUserExternalGroupChatInfo.GroupMember> membersToProcess = new ArrayList<>();
            if (groupChat.getGroupChat().getMemberList() != null) {
                membersToProcess = groupChat.getGroupChat().getMemberList().stream()
                    .filter(Objects::nonNull)
                    .filter(member -> changeUserIds.contains(member.getUserId()))
                    .collect(Collectors.toList());
            }
            membersToProcess.forEach(member -> {
                if (member.getType() == WecomChatGroupUserTypeEnum.EXTERNAL_CONTACT.getCode()) {
                    // 根据unionId 查询 群裂变邀请 信息
                    TbWecomChatGroupFissionInvite tbWecomChatGroupFissionInvite = tbWecomChatGroupFissionInviteService.getOne(Wrappers.lambdaQuery(TbWecomChatGroupFissionInvite.class)
                        .eq(TbWecomChatGroupFissionInvite::getUserUnionId, member.getUnionId())
                        .eq(TbWecomChatGroupFissionInvite::getChatId, message.getChatId())
                        .eq(TbWecomChatGroupFissionInvite::getStatus, GroupFissionInviteStatusEnum.JOINED.getCode())
                        .orderByDesc(TbWecomChatGroupFissionInvite::getCreateTime)
                        .last(Constants.MYBATIS_PLUSH_LIMIT_ONE));
                    if (ObjectUtil.isEmpty(tbWecomChatGroupFissionInvite)) {
                        // qun裂变活动id
                        TbWecomChatGroupFission tbWecomChatGroupFission = tbWecomChatGroupFissionService.getById(tbWecomChatGroupFissionInvite.getFissionId());
                        if (Objects.equals(tbWecomChatGroupFission.getStatus(), GroupFissionStatusEnum.IN_PROGRESS.getCode())) {
                            tbWecomChatGroupFissionInvite.setStatus(GroupFissionInviteStatusEnum.LEFT.getCode());
                            tbWecomChatGroupFissionInvite.setUpdateTime(new Date());
                            tbWecomChatGroupFissionInviteService.updateById(tbWecomChatGroupFissionInvite);
                        }
                    }
                }
            });
            // 更新群成员已离群
            wecomChatGroupMemberService.update(Wrappers.lambdaUpdate(TbWecomChatGroupMember.class)
                .set(TbWecomChatGroupMember::getStatus, WecomChatGroupMemberStatusEnum.QUIT_GROUP.getCode())
                .set(TbWecomChatGroupMember::getQuitTime, System.currentTimeMillis())
                .set(TbWecomChatGroupMember::getQuitScene, StrUtil.isNotEmpty(message.getQuitScene()) ? message.getQuitScene() : StrUtil.EMPTY)
                .eq(TbWecomChatGroupMember::getChatId, message.getChatId())
                .in(TbWecomChatGroupMember::getUserId, changeUserIds));
        }

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void groupChangeOwnerEventHandler(WxCpXmlMessage message) {
        // 获取群详情
        WxCpExternalContactService externalContactService = wxCpService.getExternalContactService();
        WxCpUserExternalGroupChatInfo groupChat;
        try {
            groupChat = externalContactService.getGroupChat(message.getChatId(), Constants.TRUE_1);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        // 更新群version
        TbWecomChatGroup tbWecomChatGroup = wecomChatGroupService.getOne(Wrappers.lambdaQuery(TbWecomChatGroup.class).eq(TbWecomChatGroup::getChatId, message.getChatId()));
        // 查询群详情
        tbWecomChatGroup.setMemberVersion(groupChat.getGroupChat().getMemberVersion());
        tbWecomChatGroup.setMemberNum(groupChat.getGroupChat().getMemberList().size());
        tbWecomChatGroup.setChatOwner(groupChat.getGroupChat().getOwner());
        tbWecomChatGroup.setAdminUserIds(groupChat.getGroupChat().getAdminList().stream().map(WxCpUserExternalGroupChatInfo.GroupAdmin::getUserId).collect(Collectors.joining(",")));
        tbWecomChatGroup.setUpdateTime(new Date());
        wecomChatGroupService.updateById(tbWecomChatGroup);

        TbWecomCallbackMsgInfo tbWecomCallbackMsgInfoChangeOwner = new TbWecomCallbackMsgInfo();
        tbWecomCallbackMsgInfoChangeOwner.setId(IdWorker.getId());
        tbWecomCallbackMsgInfoChangeOwner.setAgentId(message.getAgentId());
        tbWecomCallbackMsgInfoChangeOwner.setChangeType(message.getChangeType());
        tbWecomCallbackMsgInfoChangeOwner.setToUserName(message.getToUserName());
        tbWecomCallbackMsgInfoChangeOwner.setFromUserName(message.getFromUserName());
        tbWecomCallbackMsgInfoChangeOwner.setMsgCreateTime(message.getCreateTime());
        tbWecomCallbackMsgInfoChangeOwner.setUpdateDetail(message.getUpdateDetail());
        tbWecomCallbackMsgInfoChangeOwner.setMsgType(message.getMsgType());
        tbWecomCallbackMsgInfoChangeOwner.setEvent(message.getEvent());
        tbWecomCallbackMsgInfoChangeOwner.setChatId(message.getChatId());
        tbWecomCallbackMsgInfoChangeOwner.setCreateTime(new Date());
        tbWecomCallbackMsgInfoChangeOwner.setFullMsg(gson.toJson(message));
        this.save(tbWecomCallbackMsgInfoChangeOwner);
    }

    @Override
    public void groupChangeNameEventHandler(WxCpXmlMessage message) {
        // 获取群详情
        WxCpExternalContactService externalContactService = wxCpService.getExternalContactService();
        WxCpUserExternalGroupChatInfo groupChat;
        try {
            groupChat = externalContactService.getGroupChat(message.getChatId(), Constants.TRUE_1);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        // 更新群version
        TbWecomChatGroup tbWecomChatGroup = wecomChatGroupService.getOne(Wrappers.lambdaQuery(TbWecomChatGroup.class).eq(TbWecomChatGroup::getChatId, message.getChatId()));
        // 查询群详情
        tbWecomChatGroup.setMemberVersion(groupChat.getGroupChat().getMemberVersion());
        tbWecomChatGroup.setMemberNum(groupChat.getGroupChat().getMemberList().size());
        tbWecomChatGroup.setChatOwner(groupChat.getGroupChat().getOwner());
        tbWecomChatGroup.setAdminUserIds(groupChat.getGroupChat().getAdminList().stream().map(WxCpUserExternalGroupChatInfo.GroupAdmin::getUserId).collect(Collectors.joining(",")));
        tbWecomChatGroup.setChatName(groupChat.getGroupChat().getName());
        tbWecomChatGroup.setUpdateTime(new Date());
        wecomChatGroupService.updateById(tbWecomChatGroup);
        TbWecomCallbackMsgInfo tbWecomCallbackMsgInfoChageName = new TbWecomCallbackMsgInfo();
        tbWecomCallbackMsgInfoChageName.setId(IdWorker.getId());
        tbWecomCallbackMsgInfoChageName.setAgentId(message.getAgentId());
        tbWecomCallbackMsgInfoChageName.setChangeType(message.getChangeType());
        tbWecomCallbackMsgInfoChageName.setToUserName(message.getToUserName());
        tbWecomCallbackMsgInfoChageName.setFromUserName(message.getFromUserName());
        tbWecomCallbackMsgInfoChageName.setMsgCreateTime(message.getCreateTime());
        tbWecomCallbackMsgInfoChageName.setUpdateDetail(message.getUpdateDetail());
        tbWecomCallbackMsgInfoChageName.setMsgType(message.getMsgType());
        tbWecomCallbackMsgInfoChageName.setEvent(message.getEvent());
        tbWecomCallbackMsgInfoChageName.setChatId(message.getChatId());
        tbWecomCallbackMsgInfoChageName.setCreateTime(new Date());
        tbWecomCallbackMsgInfoChageName.setFullMsg(gson.toJson(message));
        this.save(tbWecomCallbackMsgInfoChageName);
    }

    @Override
    public void groupChangeNoticeEventHandler(WxCpXmlMessage message) {
        // 获取群详情
        WxCpExternalContactService externalContactService = wxCpService.getExternalContactService();
        WxCpUserExternalGroupChatInfo groupChat;
        try {
            groupChat = externalContactService.getGroupChat(message.getChatId(), Constants.TRUE_1);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        // 更新群version
        TbWecomChatGroup tbWecomChatGroup = wecomChatGroupService.getOne(Wrappers.lambdaQuery(TbWecomChatGroup.class)
            .eq(TbWecomChatGroup::getChatId, message.getChatId()));
        // 查询群详情
        tbWecomChatGroup.setMemberVersion(groupChat.getGroupChat().getMemberVersion());
        tbWecomChatGroup.setMemberNum(groupChat.getGroupChat().getMemberList().size());
        tbWecomChatGroup.setChatOwner(groupChat.getGroupChat().getOwner());
        tbWecomChatGroup.setAdminUserIds(groupChat.getGroupChat().getAdminList().stream().map(WxCpUserExternalGroupChatInfo.GroupAdmin::getUserId).collect(Collectors.joining(",")));
        tbWecomChatGroup.setChatName(groupChat.getGroupChat().getName());
        tbWecomChatGroup.setChatNotice(groupChat.getGroupChat().getNotice());
        tbWecomChatGroup.setUpdateTime(new Date());
        wecomChatGroupService.updateById(tbWecomChatGroup);
        TbWecomCallbackMsgInfo tbWecomCallbackMsgInfoChageNotice = new TbWecomCallbackMsgInfo();
        tbWecomCallbackMsgInfoChageNotice.setId(IdWorker.getId());
        tbWecomCallbackMsgInfoChageNotice.setAgentId(message.getAgentId());
        tbWecomCallbackMsgInfoChageNotice.setChangeType(message.getChangeType());
        tbWecomCallbackMsgInfoChageNotice.setToUserName(message.getToUserName());
        tbWecomCallbackMsgInfoChageNotice.setFromUserName(message.getFromUserName());
        tbWecomCallbackMsgInfoChageNotice.setMsgCreateTime(message.getCreateTime());
        tbWecomCallbackMsgInfoChageNotice.setUpdateDetail(message.getUpdateDetail());
        tbWecomCallbackMsgInfoChageNotice.setMsgType(message.getMsgType());
        tbWecomCallbackMsgInfoChageNotice.setEvent(message.getEvent());
        tbWecomCallbackMsgInfoChageNotice.setChatId(message.getChatId());
        tbWecomCallbackMsgInfoChageNotice.setCreateTime(new Date());
        tbWecomCallbackMsgInfoChageNotice.setFullMsg(gson.toJson(message));
        this.save(tbWecomCallbackMsgInfoChageNotice);
    }

    @Override
    public void groupDismissEventHandler(WxCpXmlMessage message) {
        // 移除群
        wecomChatGroupService.remove(Wrappers.lambdaQuery(TbWecomChatGroup.class)
            .eq(TbWecomChatGroup::getChatId, message.getChatId()));
        // 移除群成员
        wecomChatGroupMemberService.remove(Wrappers.lambdaQuery(TbWecomChatGroupMember.class)
            .eq(TbWecomChatGroupMember::getChatId, message.getChatId()));
        // 企微群解散
        TbWecomCallbackMsgInfo tbWecomCallbackMsgInfoChageNotice = new TbWecomCallbackMsgInfo();
        tbWecomCallbackMsgInfoChageNotice.setId(IdWorker.getId());
        tbWecomCallbackMsgInfoChageNotice.setAgentId(message.getAgentId());
        tbWecomCallbackMsgInfoChageNotice.setChangeType(message.getChangeType());
        tbWecomCallbackMsgInfoChageNotice.setToUserName(message.getToUserName());
        tbWecomCallbackMsgInfoChageNotice.setFromUserName(message.getFromUserName());
        tbWecomCallbackMsgInfoChageNotice.setMsgCreateTime(message.getCreateTime());
        tbWecomCallbackMsgInfoChageNotice.setMsgType(message.getMsgType());
        tbWecomCallbackMsgInfoChageNotice.setEvent(message.getEvent());
        tbWecomCallbackMsgInfoChageNotice.setChatId(message.getChatId());
        tbWecomCallbackMsgInfoChageNotice.setCreateTime(new Date());
        tbWecomCallbackMsgInfoChageNotice.setFullMsg(gson.toJson(message));
        this.save(tbWecomCallbackMsgInfoChageNotice);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void tagCreatEventHandler(WxCpXmlMessage message) {
        // 创建标签 或 标签组
        String tagType = message.getTagType();
        TbWecomCallbackMsgInfo tbWecomCallbackMsgInfoChageNotice = new TbWecomCallbackMsgInfo();
        tbWecomCallbackMsgInfoChageNotice.setId(IdWorker.getId());
        tbWecomCallbackMsgInfoChageNotice.setAgentId(message.getAgentId());
        tbWecomCallbackMsgInfoChageNotice.setChangeType(message.getChangeType());
        tbWecomCallbackMsgInfoChageNotice.setToUserName(message.getToUserName());
        tbWecomCallbackMsgInfoChageNotice.setFromUserName(message.getFromUserName());
        tbWecomCallbackMsgInfoChageNotice.setMsgCreateTime(message.getCreateTime());
        tbWecomCallbackMsgInfoChageNotice.setMsgType(message.getMsgType());
        tbWecomCallbackMsgInfoChageNotice.setEvent(message.getEvent());
        tbWecomCallbackMsgInfoChageNotice.setTagType(message.getTagType());
        tbWecomCallbackMsgInfoChageNotice.setCreateTime(new Date());
        tbWecomCallbackMsgInfoChageNotice.setFullMsg(gson.toJson(message));
        if (StringUtils.equals(tagType, WecomTagTypeEnum.TAG_GROUP.getCode())) {
            // 创建标签组
            tbWecomCallbackMsgInfoChageNotice.setTagGroupId(message.getId());
        }
        if (StringUtils.equals(tagType, WecomTagTypeEnum.TAG.getCode())) {
            // 创建标签
            tbWecomCallbackMsgInfoChageNotice.setTagId(message.getId());
        }
        this.save(tbWecomCallbackMsgInfoChageNotice);

        if (StringUtils.equals(tagType, WecomTagTypeEnum.TAG.getCode())) {
            // 创建标签
            // 调用api
            List<String> tagIds = new ArrayList<>();
            tagIds.add(message.getTagId());
            // 转 String[] tagId;
            WxCpUserExternalTagGroupList corpTagList;
            try {
                corpTagList = wxCpService.getExternalContactService().getCorpTagList(tagIds.toArray(new String[0]));
            } catch (WxErrorException e) {
                throw new RuntimeException(e);
            }
            List<WxCpUserExternalTagGroupList.TagGroup> tagGroupList = corpTagList.getTagGroupList();
            tagGroupList.forEach(dto -> {
                String groupId = dto.getGroupId();
                List<WxCpUserExternalTagGroupList.TagGroup.Tag> tag = dto.getTag();
                // 查询标签组是否存在 不存在就新增
                TbWecomTagGroup tbWecomTagGroup = tbWecomTagGroupService.getOne(Wrappers.lambdaQuery(TbWecomTagGroup.class).eq(TbWecomTagGroup::getGroupId, groupId));
                if (ObjectUtil.isEmpty(tbWecomTagGroup)) {
                    // 插入标签组
                    TbWecomTagGroup tbWecomTagGroupAdd = new TbWecomTagGroup();
                    tbWecomTagGroupAdd.setId(IdWorker.getId());
                    tbWecomTagGroupAdd.setGroupId(groupId);
                    tbWecomTagGroupAdd.setGroupName(dto.getGroupName());
                    tbWecomTagGroupAdd.setGroupOrder(dto.getOrder());
                    tbWecomTagGroupAdd.setGroupCreateTime(dto.getCreateTime());
                    tbWecomTagGroupAdd.setCreateTime(new Date());
                    tbWecomTagGroupAdd.setCreateBy("企微标签新增回调");
                    tbWecomTagGroupAdd.setGroupDeleted(Constants.FALSE_0);
                    tbWecomTagGroupService.save(tbWecomTagGroupAdd);
                }
                // 查询标签是否存在 不存在就新增
                tag.forEach(tagItem -> {
                    TbWecomTag tbWecomTag = tbWecomTagService.getOne(Wrappers.lambdaQuery(TbWecomTag.class).eq(TbWecomTag::getTagId, tagItem.getId()).eq(TbWecomTag::getTagGroupId, groupId));
                    if (ObjectUtil.isEmpty(tbWecomTag)) {
                        // 插入标签
                        TbWecomTag tbWecomTagAdd = new TbWecomTag();
                        tbWecomTagAdd.setId(IdWorker.getId());
                        tbWecomTagAdd.setTagGroupId(groupId);
                        tbWecomTagAdd.setTagId(tagItem.getId());
                        tbWecomTagAdd.setTagName(tagItem.getName());
                        tbWecomTagAdd.setTagOrder(tagItem.getOrder());
                        tbWecomTagAdd.setTagCreateTime(dto.getCreateTime());
                        tbWecomTagAdd.setCreateTime(new Date());
                        tbWecomTagAdd.setTagDeleted(Constants.FALSE_0);
                        tbWecomTagAdd.setCreateBy("企微标签新增回调");
                        tbWecomTagService.save(tbWecomTagAdd);
                    }
                });
            });
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void tagUpdateEventHandler(WxCpXmlMessage message) {
        // 修改 标签 或 标签组名称
        String tagType = message.getTagType();
        TbWecomCallbackMsgInfo tbWecomCallbackMsgInfoChageNotice = new TbWecomCallbackMsgInfo();
        tbWecomCallbackMsgInfoChageNotice.setId(IdWorker.getId());
        tbWecomCallbackMsgInfoChageNotice.setAgentId(message.getAgentId());
        tbWecomCallbackMsgInfoChageNotice.setChangeType(message.getChangeType());
        tbWecomCallbackMsgInfoChageNotice.setToUserName(message.getToUserName());
        tbWecomCallbackMsgInfoChageNotice.setFromUserName(message.getFromUserName());
        tbWecomCallbackMsgInfoChageNotice.setMsgCreateTime(message.getCreateTime());
        tbWecomCallbackMsgInfoChageNotice.setMsgType(message.getMsgType());
        tbWecomCallbackMsgInfoChageNotice.setEvent(message.getEvent());
        tbWecomCallbackMsgInfoChageNotice.setTagType(message.getTagType());
        tbWecomCallbackMsgInfoChageNotice.setCreateTime(new Date());
        tbWecomCallbackMsgInfoChageNotice.setFullMsg(gson.toJson(message));
        if (StringUtils.equals(tagType, WecomTagTypeEnum.TAG_GROUP.getCode())) {
            // 创建标签组
            tbWecomCallbackMsgInfoChageNotice.setTagGroupId(message.getId());
        }
        if (StringUtils.equals(tagType, WecomTagTypeEnum.TAG.getCode())) {
            // 创建标签组
            tbWecomCallbackMsgInfoChageNotice.setTagId(message.getId());
        }
        // 更新标签 //更新标签组
        if (StringUtils.equals(tagType, WecomTagTypeEnum.TAG_GROUP.getCode())) {
            // 更新标签组
            List<String> tagGroupIds = new ArrayList<>();
            tagGroupIds.add(message.getTagId());
            // 转 String[] tagId;
            WxCpUserExternalTagGroupList corpTagList;
            try {
                corpTagList = wxCpService.getExternalContactService().getCorpTagList(null, tagGroupIds.toArray(new String[0]));
            } catch (WxErrorException e) {
                throw new RuntimeException(e);
            }
            List<WxCpUserExternalTagGroupList.TagGroup> tagGroupList = corpTagList.getTagGroupList();
            tagGroupList.forEach(dto -> {
                String groupId = dto.getGroupId();
                // 查询标签组是否存在 不存在就新增
                TbWecomTagGroup tbWecomTagGroup = tbWecomTagGroupService.getOne(Wrappers.lambdaQuery(TbWecomTagGroup.class).eq(TbWecomTagGroup::getGroupId, groupId));
                if (ObjectUtil.isEmpty(tbWecomTagGroup)) {
                    // 插入标签组
                    TbWecomTagGroup tbWecomTagGroupAdd = new TbWecomTagGroup();
                    tbWecomTagGroupAdd.setId(IdWorker.getId());
                    tbWecomTagGroupAdd.setGroupId(groupId);
                    tbWecomTagGroupAdd.setGroupName(dto.getGroupName());
                    tbWecomTagGroupAdd.setGroupOrder(dto.getOrder());
                    tbWecomTagGroupAdd.setGroupCreateTime(dto.getCreateTime());
                    tbWecomTagGroupAdd.setCreateTime(new Date());
                    tbWecomTagGroupAdd.setCreateBy("企微标签修改回调");
                    tbWecomTagGroupAdd.setGroupDeleted(Constants.FALSE_0);
                    tbWecomTagGroupService.save(tbWecomTagGroupAdd);
                } else {
                    // 修改标签组
                    tbWecomTagGroup.setGroupId(groupId);
                    tbWecomTagGroup.setGroupName(dto.getGroupName());
                    tbWecomTagGroup.setGroupOrder(dto.getOrder());
                    tbWecomTagGroup.setGroupCreateTime(dto.getCreateTime());
                    tbWecomTagGroup.setUpdateTime(new Date());
                    tbWecomTagGroup.setUpdateBy("企微标签修改回调");
                    tbWecomTagGroup.setGroupDeleted(Constants.FALSE_0);
                    tbWecomTagGroupService.updateById(tbWecomTagGroup);
                }
            });
        }

        if (StringUtils.equals(tagType, WecomTagTypeEnum.TAG.getCode())) {
            // 更新标签
            List<String> tagIds = new ArrayList<>();
            tagIds.add(message.getTagId());
            // 转 String[] tagId;
            WxCpUserExternalTagGroupList corpTagList;
            try {
                corpTagList = wxCpService.getExternalContactService().getCorpTagList(tagIds.toArray(new String[0]));
            } catch (WxErrorException e) {
                throw new RuntimeException(e);
            }

            List<WxCpUserExternalTagGroupList.TagGroup> tagGroupList = corpTagList.getTagGroupList();
            tagGroupList.forEach(dto -> {
                String groupId = dto.getGroupId();
                List<WxCpUserExternalTagGroupList.TagGroup.Tag> tag = dto.getTag();
                // 查询标签组是否存在 不存在就新增
                TbWecomTagGroup tbWecomTagGroup = tbWecomTagGroupService.getOne(Wrappers.lambdaQuery(TbWecomTagGroup.class).eq(TbWecomTagGroup::getGroupId, groupId));
                if (ObjectUtil.isEmpty(tbWecomTagGroup)) {
                    // 插入标签组
                    TbWecomTagGroup tbWecomTagGroupAdd = new TbWecomTagGroup();
                    tbWecomTagGroupAdd.setId(IdWorker.getId());
                    tbWecomTagGroupAdd.setGroupId(groupId);
                    tbWecomTagGroupAdd.setGroupName(dto.getGroupName());
                    tbWecomTagGroupAdd.setGroupOrder(dto.getOrder());
                    tbWecomTagGroupAdd.setGroupCreateTime(dto.getCreateTime());
                    tbWecomTagGroupAdd.setCreateTime(new Date());
                    tbWecomTagGroupAdd.setCreateBy("企微标签修改回调");
                    tbWecomTagGroupAdd.setGroupDeleted(Constants.FALSE_0);
                    tbWecomTagGroupService.save(tbWecomTagGroupAdd);
                }
                // 查询标签是否存在 不存在就新增
                tag.forEach(tagItem -> {
                    TbWecomTag tbWecomTag = tbWecomTagService.getOne(Wrappers.lambdaQuery(TbWecomTag.class).eq(TbWecomTag::getTagId, tagItem.getId()).eq(TbWecomTag::getTagGroupId, groupId));
                    if (ObjectUtil.isEmpty(tbWecomTag)) {
                        // 插入标签
                        TbWecomTag tbWecomTagAdd = new TbWecomTag();
                        tbWecomTagAdd.setId(IdWorker.getId());
                        tbWecomTagAdd.setTagGroupId(groupId);
                        tbWecomTagAdd.setTagId(tagItem.getId());
                        tbWecomTagAdd.setTagName(tagItem.getName());
                        tbWecomTagAdd.setTagOrder(tagItem.getOrder());
                        tbWecomTagAdd.setTagCreateTime(dto.getCreateTime());
                        tbWecomTagAdd.setTagDeleted(Constants.FALSE_0);
                        tbWecomTagAdd.setCreateTime(new Date());
                        tbWecomTagAdd.setCreateBy("企微标签修改回调");
                        tbWecomTagService.save(tbWecomTagAdd);
                    } else {
                        // 修改标签
                        tbWecomTag.setTagGroupId(groupId);
                        tbWecomTag.setTagId(tagItem.getId());
                        tbWecomTag.setTagName(tagItem.getName());
                        tbWecomTag.setTagOrder(tagItem.getOrder());
                        tbWecomTag.setTagCreateTime(dto.getCreateTime());
                        tbWecomTag.setUpdateTime(new Date());
                        tbWecomTag.setUpdateBy("企微标签修改回调");
                        tbWecomTag.setTagDeleted(Constants.FALSE_0);
                        tbWecomTagService.updateById(tbWecomTag);
                    }
                });
            });
        }
        this.save(tbWecomCallbackMsgInfoChageNotice);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void tagDeleteEventHandler(WxCpXmlMessage message) {
        // 删除标签 与 标签组事件
        String tagType = message.getTagType();
        TbWecomCallbackMsgInfo tbWecomCallbackMsgInfoChageNotice = new TbWecomCallbackMsgInfo();
        tbWecomCallbackMsgInfoChageNotice.setId(IdWorker.getId());
        tbWecomCallbackMsgInfoChageNotice.setAgentId(message.getAgentId());
        tbWecomCallbackMsgInfoChageNotice.setChangeType(message.getChangeType());
        tbWecomCallbackMsgInfoChageNotice.setToUserName(message.getToUserName());
        tbWecomCallbackMsgInfoChageNotice.setFromUserName(message.getFromUserName());
        tbWecomCallbackMsgInfoChageNotice.setMsgCreateTime(message.getCreateTime());
        tbWecomCallbackMsgInfoChageNotice.setMsgType(message.getMsgType());
        tbWecomCallbackMsgInfoChageNotice.setEvent(message.getEvent());
        tbWecomCallbackMsgInfoChageNotice.setTagType(message.getTagType());
        tbWecomCallbackMsgInfoChageNotice.setCreateTime(new Date());
        tbWecomCallbackMsgInfoChageNotice.setFullMsg(gson.toJson(message));
        if (StringUtils.equals(tagType, WecomTagTypeEnum.TAG_GROUP.getCode())) {
            // 删除标签组
            tbWecomCallbackMsgInfoChageNotice.setTagGroupId(message.getId());
        }
        if (StringUtils.equals(tagType, WecomTagTypeEnum.TAG.getCode())) {
            // 删除标签
            tbWecomCallbackMsgInfoChageNotice.setTagId(message.getId());
        }
        if (StringUtils.equals(tagType, WecomTagTypeEnum.TAG_GROUP.getCode())) {
            // 删除标签组
            tbWecomTagGroupService.remove(Wrappers.lambdaQuery(TbWecomTagGroup.class)
                .eq(TbWecomTagGroup::getGroupId, message.getId()));
            // 删除标签
            tbWecomTagService.remove(Wrappers.lambdaQuery(TbWecomTag.class)
                .eq(TbWecomTag::getTagGroupId, message.getId()));
        }
        if (StringUtils.equals(tagType, WecomTagTypeEnum.TAG.getCode())) {
            // 删除标签
            tbWecomTagService.remove(Wrappers.lambdaQuery(TbWecomTag.class)
                .eq(TbWecomTag::getTagId, message.getId()));
        }
        this.save(tbWecomCallbackMsgInfoChageNotice);
    }

    @Override
    public void tagShuffleEventHandler(WxCpXmlMessage message) {
        TbWecomCallbackMsgInfo tbWecomCallbackMsgInfoChageNotice = new TbWecomCallbackMsgInfo();
        tbWecomCallbackMsgInfoChageNotice.setId(IdWorker.getId());
        tbWecomCallbackMsgInfoChageNotice.setAgentId(message.getAgentId());
        tbWecomCallbackMsgInfoChageNotice.setChangeType(message.getChangeType());
        tbWecomCallbackMsgInfoChageNotice.setToUserName(message.getToUserName());
        tbWecomCallbackMsgInfoChageNotice.setFromUserName(message.getFromUserName());
        tbWecomCallbackMsgInfoChageNotice.setMsgCreateTime(message.getCreateTime());
        tbWecomCallbackMsgInfoChageNotice.setMsgType(message.getMsgType());
        tbWecomCallbackMsgInfoChageNotice.setEvent(message.getEvent());
        // 标签组的id，表示只有此标签组内的标签发生了重排，如果为空，则表示全部标签组顺序都发生了变化
        tbWecomCallbackMsgInfoChageNotice.setTagGroupId(StringUtils.isEmpty(message.getId()) ? StrUtil.EMPTY : message.getId());
        tbWecomCallbackMsgInfoChageNotice.setCreateTime(new Date());
        tbWecomCallbackMsgInfoChageNotice.setFullMsg(gson.toJson(message));

        if (StringUtils.isEmpty(message.getId())) {
            // 同步全量数据 更新
            // 同步企微全部 标签组 与 标签 信息
            WxCpUserExternalTagGroupList corpTagList;
            try {
                corpTagList = wxCpService.getExternalContactService().getCorpTagList(null, null);
            } catch (WxErrorException e) {
                throw new RuntimeException(e);
            }
            List<WxCpUserExternalTagGroupList.TagGroup> tagGroupList = corpTagList.getTagGroupList();
            tbWecomTagGroupService.remove(Wrappers.lambdaQuery(TbWecomTagGroup.class).eq(TbWecomTagGroup::getGroupDeleted, 0));
            tbWecomTagService.remove(Wrappers.lambdaQuery(TbWecomTag.class).eq(TbWecomTag::getTagDeleted, 0));
            List<TbWecomTagGroup> tbWecomTagGroupList = new ArrayList<>();
            for (WxCpUserExternalTagGroupList.TagGroup tagGroup : tagGroupList) {
                TbWecomTagGroup tbWecomTagGroup = new TbWecomTagGroup();
                tbWecomTagGroup.setId(IdWorker.getId());
                tbWecomTagGroup.setGroupId(tagGroup.getGroupId());
                tbWecomTagGroup.setGroupName(tagGroup.getGroupName());
                tbWecomTagGroup.setGroupOrder(tagGroup.getOrder());
                tbWecomTagGroup.setGroupCreateTime(tagGroup.getCreateTime());
                tbWecomTagGroup.setGroupDeleted(Constants.FALSE_0);
                tbWecomTagGroup.setCreateTime(new Date());
                tbWecomTagGroupList.add(tbWecomTagGroup);
                List<WxCpUserExternalTagGroupList.TagGroup.Tag> tag = tagGroup.getTag();
                List<TbWecomTag> tbWecomTagList = new ArrayList<>();
                for (WxCpUserExternalTagGroupList.TagGroup.Tag tagGroupTag : tag) {
                    TbWecomTag tagBean = new TbWecomTag();
                    tagBean.setId(IdWorker.getId());
                    tagBean.setTagGroupId(tagGroup.getGroupId());
                    tagBean.setTagId(tagGroupTag.getId());
                    tagBean.setTagName(tagGroupTag.getName());
                    tagBean.setTagCreateTime(tagGroupTag.getCreateTime());
                    tagBean.setTagOrder(tagGroupTag.getOrder());
                    tagBean.setTagDeleted(Constants.FALSE_0);
                    tbWecomTagList.add(tagBean);
                }
                tbWecomTagService.saveBatch(tbWecomTagList);
            }
            tbWecomTagGroupService.saveBatch(tbWecomTagGroupList);
        } else {
            // 标签组id 内的标签排序发生变化
            List<String> tagGroupIds = new ArrayList<>();
            tagGroupIds.add(message.getTagId());
            // 转 String[] tagId;
            WxCpUserExternalTagGroupList corpTagList;
            try {
                corpTagList = wxCpService.getExternalContactService().getCorpTagList(null, tagGroupIds.toArray(new String[0]));
            } catch (WxErrorException e) {
                throw new RuntimeException(e);
            }
            // 删除 指定组标签
            tbWecomTagGroupService.remove(Wrappers.lambdaQuery(TbWecomTagGroup.class).eq(TbWecomTagGroup::getGroupId, message.getId()));
            // 删除 指定标签
            tbWecomTagService.remove(Wrappers.lambdaQuery(TbWecomTag.class).eq(TbWecomTag::getTagGroupId, message.getId()));
            List<WxCpUserExternalTagGroupList.TagGroup> tagGroupList = corpTagList.getTagGroupList();
            List<TbWecomTagGroup> tbWecomTagGroupList = new ArrayList<>();
            for (WxCpUserExternalTagGroupList.TagGroup tagGroup : tagGroupList) {
                TbWecomTagGroup tbWecomTagGroup = new TbWecomTagGroup();
                tbWecomTagGroup.setId(IdWorker.getId());
                tbWecomTagGroup.setGroupId(tagGroup.getGroupId());
                tbWecomTagGroup.setGroupName(tagGroup.getGroupName());
                tbWecomTagGroup.setGroupOrder(tagGroup.getOrder());
                tbWecomTagGroup.setGroupCreateTime(tagGroup.getCreateTime());
                tbWecomTagGroup.setGroupDeleted(Constants.FALSE_0);
                tbWecomTagGroup.setCreateTime(new Date());
                tbWecomTagGroupList.add(tbWecomTagGroup);
                List<WxCpUserExternalTagGroupList.TagGroup.Tag> tag = tagGroup.getTag();
                List<TbWecomTag> tbWecomTagList = new ArrayList<>();
                for (WxCpUserExternalTagGroupList.TagGroup.Tag tagGroupTag : tag) {
                    TbWecomTag tagBean = new TbWecomTag();
                    tagBean.setId(IdWorker.getId());
                    tagBean.setTagGroupId(tagGroup.getGroupId());
                    tagBean.setTagId(tagGroupTag.getId());
                    tagBean.setTagName(tagGroupTag.getName());
                    tagBean.setTagCreateTime(tagGroupTag.getCreateTime());
                    tagBean.setTagOrder(tagGroupTag.getOrder());
                    tagBean.setTagDeleted(Constants.FALSE_0);
                    tbWecomTagList.add(tagBean);
                }
                tbWecomTagService.saveBatch(tbWecomTagList);
            }
            tbWecomTagGroupService.saveBatch(tbWecomTagGroupList);
        }
        this.save(tbWecomCallbackMsgInfoChageNotice);
    }

    @Override
    public void addExternalContactHandler(WxCpXmlMessage message) {
        // 1. 保存回调消息
        TbWecomCallbackMsgInfo callbackMsg = new TbWecomCallbackMsgInfo();
        callbackMsg.setId(IdWorker.getId());
        callbackMsg.setAgentId(message.getAgentId());
        callbackMsg.setChangeType(message.getChangeType());
        callbackMsg.setToUserName(message.getToUserName());
        callbackMsg.setFromUserName(message.getFromUserName());
        callbackMsg.setMsgCreateTime(message.getCreateTime());
        callbackMsg.setMsgType(message.getMsgType());
        callbackMsg.setEvent(message.getEvent());
        callbackMsg.setUserId(message.getUserId());
        callbackMsg.setExternalUserId(message.getExternalUserId());
        callbackMsg.setState(getSafeString(message.getState()));
        callbackMsg.setWelcomeCode(getSafeString(message.getWelcomeCode()));
        callbackMsg.setCreateTime(new Date());
        callbackMsg.setFullMsg(gson.toJson(message));
        this.save(callbackMsg);
        // 2. 获取客户详情
        WxCpExternalContactInfo contactDetail = getContactDetail(message.getExternalUserId());
        if (ObjectUtil.isEmpty(contactDetail)) return;
        ExternalContact externalContact = contactDetail.getExternalContact();
        List<FollowedUser> followedUsers = contactDetail.getFollowedUsers();
        // 3. 处理客户信息
        handleCustomerInfo(externalContact, followedUsers, message);
    }


    /**
     * 获取客户详情
     */
    private WxCpExternalContactInfo getContactDetail(String externalUserId) {
        try {
            return wxCpService.getExternalContactService().getContactDetail(externalUserId, "");
        } catch (WxErrorException e) {
            log.error("获取客户详情失败 externalUserId: {}", externalUserId, e);
            throw new RuntimeException("获取客户详情失败", e);
        }
    }

    /**
     * 处理客户信息
     */
    private synchronized void handleCustomerInfo(ExternalContact externalContact,
                                                 List<FollowedUser> followedUsers,
                                                 WxCpXmlMessage message) {
        // 处理客户基本信息
        handleCustomerBaseInfo(externalContact);
        // 处理跟进人关系
        handleFollowUserRelation(externalContact, followedUsers, message);
    }

    /**
     * 处理客户基本信息
     */
    private void handleCustomerBaseInfo(ExternalContact externalContact) {
        boolean customerExists = tbWecomExternalContactCustomerService.count(
            Wrappers.lambdaQuery(TbWecomExternalContactCustomer.class)
                .eq(TbWecomExternalContactCustomer::getExternalUserid, externalContact.getExternalUserId())
        ) > 0;
        if (!customerExists) {
            TbWecomExternalContactCustomer customer = buildCustomerEntity(externalContact);
            tbWecomExternalContactCustomerService.save(customer);
        } else {
            TbWecomExternalContactCustomer tbWecomExternalContactCustomer = tbWecomExternalContactCustomerService
                .getOne(Wrappers.lambdaQuery(TbWecomExternalContactCustomer.class)
                    .eq(TbWecomExternalContactCustomer::getExternalUserid, externalContact.getExternalUserId())
                    .last(Constants.MYBATIS_PLUSH_LIMIT_ONE)
                );
            tbWecomExternalContactCustomer.setName(externalContact.getName());
            tbWecomExternalContactCustomer.setAvatar(externalContact.getAvatar());
            tbWecomExternalContactCustomer.setGender(externalContact.getGender());
            tbWecomExternalContactCustomerService.updateById(tbWecomExternalContactCustomer);
        }
    }

    /**
     * 构建客户实体
     */
    private TbWecomExternalContactCustomer buildCustomerEntity(ExternalContact externalContact) {
        TbWecomExternalContactCustomer customer = new TbWecomExternalContactCustomer();
        customer.setId(IdWorker.getId());
        customer.setExternalUserid(externalContact.getExternalUserId());
        customer.setName(getSafeString(externalContact.getName()));
        customer.setAvatar(getSafeString(externalContact.getAvatar()));
        customer.setType(externalContact.getType());
        customer.setGender(externalContact.getGender());
        customer.setUnionid(getSafeString(externalContact.getUnionId()));
        customer.setPosition(getSafeString(externalContact.getPosition()));
        customer.setCorpName(getSafeString(externalContact.getCorpName()));
        customer.setCorpFullName(getSafeString(externalContact.getCorpFullName()));
        customer.setCreateTime(new Date());
        return customer;
    }

    /**
     * 处理跟进人关系
     */
    private void handleFollowUserRelation(ExternalContact externalContact,
                                          List<FollowedUser> followedUsers,
                                          WxCpXmlMessage message) {
        if (CollectionUtils.isEmpty(followedUsers)) return;

        // 找到对应的跟进人
        FollowedUser targetFollowUser = followedUsers.stream()
            .filter(ft -> StringUtils.equals(ft.getUserId(), message.getUserId()))
            .findFirst()
            .orElse(null);

        if (ObjectUtil.isNotEmpty(targetFollowUser)) return;

        // 检查关系是否已存在
        boolean relationExists = tbWecomExternalContactCustomerFollowUserService.count(
            Wrappers.lambdaQuery(TbWecomExternalContactCustomerFollowUser.class)
                .eq(TbWecomExternalContactCustomerFollowUser::getStatus, 0)
                .eq(TbWecomExternalContactCustomerFollowUser::getExternalUserid, message.getExternalUserId())
                .eq(TbWecomExternalContactCustomerFollowUser::getUserId, message.getUserId())
        ) > 0;
        if (!relationExists) {
            saveFollowUserRelation(externalContact, targetFollowUser, message);
        }
    }

    /**
     * 保存跟进人关系
     */
    private void saveFollowUserRelation(ExternalContact externalContact,
                                        FollowedUser followedUser,
                                        WxCpXmlMessage message) {
        // 保存主关系
        TbWecomExternalContactCustomerFollowUser followUserEntity = buildFollowUserEntity(
            externalContact, followedUser, message);
        tbWecomExternalContactCustomerFollowUserService.save(followUserEntity);
        // 保存标签关系
        saveFollowUserTags(externalContact, followedUser);
    }

    /**
     * 构建跟进人实体
     */
    private TbWecomExternalContactCustomerFollowUser buildFollowUserEntity(
        ExternalContact externalContact, FollowedUser followedUser, WxCpXmlMessage message) {
        TbWecomExternalContactCustomerFollowUser entity = new TbWecomExternalContactCustomerFollowUser();
        entity.setId(IdWorker.getId());
        entity.setExternalUserid(externalContact.getExternalUserId());
        entity.setUserId(followedUser.getUserId());
        entity.setRemark(getSafeString(followedUser.getRemark()));
        entity.setDescription(getSafeString(followedUser.getDescription()));
        entity.setAddTime(followedUser.getCreateTime());
        entity.setRemarkCorpName(getSafeString(followedUser.getRemarkCorpName()));
        entity.setRemarkMobiles(ObjectUtil.isNotEmpty(followedUser.getRemarkMobiles()) ? String.join(",", followedUser.getRemarkMobiles()) : StrUtil.EMPTY);
        entity.setAddWay(Integer.valueOf(followedUser.getAddWay()));
        entity.setDelType(WecomMsgCallBackExternalContactChangeTypeEnum.ADD_EXTERNAL_CONTACT.getCode());
        entity.setOperUserid(followedUser.getOperatorUserId());
        entity.setState(followedUser.getState());
        // 处理视频号信息
        handleWechatChannelsInfo(entity, followedUser.getWechatChannels());
        // 处理标签信息
        entity.setTagIds(buildTagIdsString(followedUser.getTags()));
        return entity;
    }

    /**
     * 保存跟进人标签
     */
    private void saveFollowUserTags(ExternalContact externalContact, FollowedUser followedUser) {
        if (ObjectUtil.isEmpty(followedUser.getTags())) return;
        List<TbWecomExternalContactCustomerFollowUserTag> tagEntities =
            Arrays.stream(followedUser.getTags())
                .filter(Objects::nonNull)
                .filter(tag -> StringUtils.isNotBlank(tag.getTagId()))
                .map(tag -> buildFollowUserTagEntity(externalContact, followedUser, tag))
                .collect(Collectors.toList());
        if (!tagEntities.isEmpty()) {
            tbWecomExternalContactCustomerFollowUserTagService.saveBatch(tagEntities);
        }
    }

    /**
     * 构建标签实体
     */
    private TbWecomExternalContactCustomerFollowUserTag buildFollowUserTagEntity(
        ExternalContact externalContact, FollowedUser followedUser, FollowedUser.Tag tag) {

        TbWecomExternalContactCustomerFollowUserTag tagEntity =
            new TbWecomExternalContactCustomerFollowUserTag();
        tagEntity.setId(IdWorker.getId());
        tagEntity.setExternalUserid(externalContact.getExternalUserId());
        tagEntity.setUserId(followedUser.getUserId());
        tagEntity.setTagId(tag.getTagId());
        tagEntity.setCreateTime(new Date());
        return tagEntity;
    }

    /**
     * 构建标签ID字符串
     */
    private String buildTagIdsString(FollowedUser.Tag[] tags) {
        if (ObjectUtil.isEmpty(tags)) return StrUtil.EMPTY;

        return Arrays.stream(tags)
            .filter(Objects::nonNull)
            .map(FollowedUser.Tag::getTagId)
            .filter(StringUtils::isNotBlank)
            .collect(Collectors.joining(","));
    }

    /**
     * 处理视频号信息
     */
    private void handleWechatChannelsInfo(TbWecomExternalContactCustomerFollowUser entity,
                                          FollowedUser.WechatChannels wechatChannels) {
        if (ObjectUtil.isNotEmpty(wechatChannels)) {
            entity.setWechatChannelsNickname(wechatChannels.getNickname());
            entity.setWechatChannelsSource(wechatChannels.getSource());
        }
    }

    /**
     * 安全获取字符串
     */
    private String getSafeString(String value) {
        return StringUtils.isNotEmpty(value) ? value : StrUtil.EMPTY;
    }


    @Override
    public void editExternalContactHandler(WxCpXmlMessage message) {
        // 修改客户信息
        TbWecomCallbackMsgInfo tbWecomCallbackMsgInfoChageNotice = new TbWecomCallbackMsgInfo();
        tbWecomCallbackMsgInfoChageNotice.setId(IdWorker.getId());
        tbWecomCallbackMsgInfoChageNotice.setAgentId(message.getAgentId());
        tbWecomCallbackMsgInfoChageNotice.setChangeType(message.getChangeType());
        tbWecomCallbackMsgInfoChageNotice.setToUserName(message.getToUserName());
        tbWecomCallbackMsgInfoChageNotice.setFromUserName(message.getFromUserName());
        tbWecomCallbackMsgInfoChageNotice.setMsgCreateTime(message.getCreateTime());
        tbWecomCallbackMsgInfoChageNotice.setMsgType(message.getMsgType());
        tbWecomCallbackMsgInfoChageNotice.setEvent(message.getEvent());
        tbWecomCallbackMsgInfoChageNotice.setUserId(message.getUserId());
        tbWecomCallbackMsgInfoChageNotice.setExternalUserId(message.getExternalUserId());
        tbWecomCallbackMsgInfoChageNotice.setState(StringUtils.isNotEmpty(message.getState()) ? message.getState() : StrUtil.EMPTY);
        tbWecomCallbackMsgInfoChageNotice.setWelcomeCode(StringUtils.isNotEmpty(message.getWelcomeCode()) ? message.getWelcomeCode() : StrUtil.EMPTY);
        tbWecomCallbackMsgInfoChageNotice.setCreateTime(new Date());
        tbWecomCallbackMsgInfoChageNotice.setFullMsg(gson.toJson(message));
        this.save(tbWecomCallbackMsgInfoChageNotice);

        // 配置了客户联系功能的成员修改外部联系人的备注、手机号或标签时
        WxCpExternalContactService externalContactService = wxCpService.getExternalContactService();
        WxCpExternalContactInfo contactDetail;
        try {
            contactDetail = externalContactService.getContactDetail(message.getExternalUserId(), StrUtil.EMPTY);
        } catch (WxErrorException e) {
            throw new RuntimeException(e);
        }
        ExternalContact externalContact = contactDetail.getExternalContact();
        List<FollowedUser> followedUsers = contactDetail.getFollowedUsers();
        // 查询 客户是否存在
        if (tbWecomExternalContactCustomerService.count(Wrappers.lambdaQuery(TbWecomExternalContactCustomer.class)
            .eq(TbWecomExternalContactCustomer::getExternalUserid, externalContact.getExternalUserId())) > 0) {
            // 客户存在 更新客户信息
            TbWecomExternalContactCustomer tbWecomExternalContactCustomer = tbWecomExternalContactCustomerService
                .getOne(Wrappers.lambdaQuery(TbWecomExternalContactCustomer.class)
                    .eq(TbWecomExternalContactCustomer::getExternalUserid, message.getExternalUserId())
                    .orderByDesc(TbWecomExternalContactCustomer::getCreateTime)
                    .last(Constants.MYBATIS_PLUSH_LIMIT_ONE)
                );
            tbWecomExternalContactCustomer.setName(externalContact.getName());
            tbWecomExternalContactCustomer.setAvatar(externalContact.getAvatar());
            tbWecomExternalContactCustomer.setGender(externalContact.getGender());
            tbWecomExternalContactCustomerService.updateById(tbWecomExternalContactCustomer);
            // 客户存在 更新手机号 备注 手机号 标签
            // 查询客户联系是否存在
            TbWecomExternalContactCustomerFollowUser tbWecomExternalContactCustomerFollowUser = tbWecomExternalContactCustomerFollowUserService.getOne(Wrappers.lambdaQuery(TbWecomExternalContactCustomerFollowUser.class)
                .eq(TbWecomExternalContactCustomerFollowUser::getStatus, WecomCustomerStatusEnum.NOT_LOST.getCode())
                .eq(TbWecomExternalContactCustomerFollowUser::getExternalUserid, message.getExternalUserId())
                .eq(TbWecomExternalContactCustomerFollowUser::getUserId, message.getUserId())
                .last(Constants.MYBATIS_PLUSH_LIMIT_ONE)
            );
            if (ObjectUtil.isNotEmpty(tbWecomExternalContactCustomerFollowUser)) {
                FollowedUser followedUser = followedUsers.stream().filter(ft -> StringUtils.equals(ft.getUserId(), message.getUserId())).findAny().orElse(null);
                if (ObjectUtil.isNotEmpty(followedUser)) {
                    // 更新手机号
                    assert followedUser != null;
                    tbWecomExternalContactCustomerFollowUser.setRemarkMobiles(ObjectUtil.isNotEmpty(followedUser.getRemarkMobiles()) ? String.join(",", followedUser.getRemarkMobiles()) : StrUtil.EMPTY);
                    tbWecomExternalContactCustomerFollowUser.setRemark(followedUser.getRemark());
                    // 更新标签
                    // 删除旧标签数据
                    tbWecomExternalContactCustomerFollowUserTagService.remove(Wrappers.lambdaQuery(TbWecomExternalContactCustomerFollowUserTag.class).eq(TbWecomExternalContactCustomerFollowUserTag::getExternalUserid, message.getExternalUserId()).eq(TbWecomExternalContactCustomerFollowUserTag::getUserId, message.getUserId()));
                    if (ObjectUtil.isNotEmpty(followedUser.getTags())) {
                        FollowedUser.Tag[] tags = followedUser.getTags();
                        // 取 tags 中Tag 实体 tagId 用，隔开
                        String tagIds = tags == null ? "" :
                            Arrays.stream(tags)
                                .filter(Objects::nonNull) // 过滤掉 null 的 Tag 对象
                                .map(FollowedUser.Tag::getTagId)       // 使用方法引用
                                .filter(tagId -> tagId != null && !tagId.trim().isEmpty()) // 过滤空 tagId
                                .collect(Collectors.joining(","));
                        tbWecomExternalContactCustomerFollowUser.setTagIds(tagIds);
                        List<TbWecomExternalContactCustomerFollowUserTag> customerFollowUserTag = new ArrayList<>();
                        assert tags != null;
                        for (FollowedUser.Tag tag : tags) {
                            TbWecomExternalContactCustomerFollowUserTag tbWecomExternalContactCustomerFollowUserTag = new TbWecomExternalContactCustomerFollowUserTag();
                            tbWecomExternalContactCustomerFollowUserTag.setId(IdWorker.getId());
                            tbWecomExternalContactCustomerFollowUserTag.setExternalUserid(externalContact.getExternalUserId());
                            tbWecomExternalContactCustomerFollowUserTag.setUserId(followedUser.getUserId());
                            tbWecomExternalContactCustomerFollowUserTag.setTagId(tag.getTagId());
                            tbWecomExternalContactCustomerFollowUserTag.setCreateTime(new Date());
                            customerFollowUserTag.add(tbWecomExternalContactCustomerFollowUserTag);
                        }
                        // 新增新标签数据
                        tbWecomExternalContactCustomerFollowUserTagService.saveBatch(customerFollowUserTag);
                    } else {
                        tbWecomExternalContactCustomerFollowUser.setTagIds(StrUtil.EMPTY);
                    }
                    tbWecomExternalContactCustomerFollowUserService.updateById(tbWecomExternalContactCustomerFollowUser);
                }

            }
        }
    }

    @Override
    public void delExternalContactHandler(WxCpXmlMessage message) {
        // 配置了客户联系功能的成员删除外部联系人时
        TbWecomCallbackMsgInfo tbWecomCallbackMsgInfoChageNotice = new TbWecomCallbackMsgInfo();
        tbWecomCallbackMsgInfoChageNotice.setId(IdWorker.getId());
        tbWecomCallbackMsgInfoChageNotice.setAgentId(message.getAgentId());
        tbWecomCallbackMsgInfoChageNotice.setChangeType(message.getChangeType());
        tbWecomCallbackMsgInfoChageNotice.setToUserName(message.getToUserName());
        tbWecomCallbackMsgInfoChageNotice.setFromUserName(message.getFromUserName());
        tbWecomCallbackMsgInfoChageNotice.setMsgCreateTime(message.getCreateTime());
        tbWecomCallbackMsgInfoChageNotice.setMsgType(message.getMsgType());
        tbWecomCallbackMsgInfoChageNotice.setEvent(message.getEvent());
        tbWecomCallbackMsgInfoChageNotice.setUserId(message.getUserId());
        tbWecomCallbackMsgInfoChageNotice.setExternalUserId(message.getExternalUserId());
        tbWecomCallbackMsgInfoChageNotice.setSource(StrUtil.isNotEmpty(message.getSource()) ? message.getSource() : StrUtil.EMPTY);
        tbWecomCallbackMsgInfoChageNotice.setCreateTime(new Date());
        tbWecomCallbackMsgInfoChageNotice.setFullMsg(gson.toJson(message));
        this.save(tbWecomCallbackMsgInfoChageNotice);
        // 查询数据库中的数据更新数据
        TbWecomExternalContactCustomerFollowUser tbWecomExternalContactCustomerFollowUser = tbWecomExternalContactCustomerFollowUserService.getOne(Wrappers.lambdaQuery(TbWecomExternalContactCustomerFollowUser.class)
            .eq(TbWecomExternalContactCustomerFollowUser::getExternalUserid, message.getExternalUserId())
            .eq(TbWecomExternalContactCustomerFollowUser::getUserId, message.getUserId())
            .eq(TbWecomExternalContactCustomerFollowUser::getStatus, WecomCustomerStatusEnum.NOT_LOST.getCode())
            .last(Constants.MYBATIS_PLUSH_LIMIT_ONE)
        );
        if (ObjectUtil.isNotEmpty(tbWecomExternalContactCustomerFollowUser)) {
            // 更新状态
            tbWecomExternalContactCustomerFollowUser.setDelType(WecomMsgCallBackExternalContactChangeTypeEnum.DEL_EXTERNAL_CONTACT.getCode());
            tbWecomExternalContactCustomerFollowUser.setOperUserid(message.getUserId());
            tbWecomExternalContactCustomerFollowUser.setTagIds(StrUtil.EMPTY);
            tbWecomExternalContactCustomerFollowUser.setStatus(WecomCustomerStatusEnum.LOST.getCode());
            tbWecomExternalContactCustomerFollowUser.setLostTime(System.currentTimeMillis());
            tbWecomExternalContactCustomerFollowUserService.updateById(tbWecomExternalContactCustomerFollowUser);
            // 删除标签
            tbWecomExternalContactCustomerFollowUserTagService.remove(Wrappers.lambdaQuery(TbWecomExternalContactCustomerFollowUserTag.class)
                .eq(TbWecomExternalContactCustomerFollowUserTag::getUserId, message.getUserId())
                .eq(TbWecomExternalContactCustomerFollowUserTag::getExternalUserid, message.getExternalUserId())
            );
        }
    }

    @Override
    public void delFollowUser(WxCpXmlMessage message) {
        // 配置了客户联系功能的成员被外部联系人删除时
        TbWecomCallbackMsgInfo tbWecomCallbackMsgInfoChageNotice = new TbWecomCallbackMsgInfo();
        tbWecomCallbackMsgInfoChageNotice.setId(IdWorker.getId());
        tbWecomCallbackMsgInfoChageNotice.setAgentId(message.getAgentId());
        tbWecomCallbackMsgInfoChageNotice.setChangeType(message.getChangeType());
        tbWecomCallbackMsgInfoChageNotice.setToUserName(message.getToUserName());
        tbWecomCallbackMsgInfoChageNotice.setFromUserName(message.getFromUserName());
        tbWecomCallbackMsgInfoChageNotice.setMsgCreateTime(message.getCreateTime());
        tbWecomCallbackMsgInfoChageNotice.setMsgType(message.getMsgType());
        tbWecomCallbackMsgInfoChageNotice.setEvent(message.getEvent());
        tbWecomCallbackMsgInfoChageNotice.setUserId(message.getUserId());
        tbWecomCallbackMsgInfoChageNotice.setExternalUserId(message.getExternalUserId());
        tbWecomCallbackMsgInfoChageNotice.setCreateTime(new Date());
        tbWecomCallbackMsgInfoChageNotice.setFullMsg(gson.toJson(message));
        this.save(tbWecomCallbackMsgInfoChageNotice);
        // 查询数据库中的数据更新数据
        TbWecomExternalContactCustomerFollowUser tbWecomExternalContactCustomerFollowUser = tbWecomExternalContactCustomerFollowUserService.getOne(Wrappers.lambdaQuery(TbWecomExternalContactCustomerFollowUser.class)
            .eq(TbWecomExternalContactCustomerFollowUser::getExternalUserid, message.getExternalUserId())
            .eq(TbWecomExternalContactCustomerFollowUser::getUserId, message.getUserId())
            .eq(TbWecomExternalContactCustomerFollowUser::getStatus, WecomCustomerStatusEnum.NOT_LOST.getCode())
            .last(Constants.MYBATIS_PLUSH_LIMIT_ONE)
        );
        if (ObjectUtil.isNotEmpty(tbWecomExternalContactCustomerFollowUser)) {
            // 更新状态
            tbWecomExternalContactCustomerFollowUser.setDelType(WecomMsgCallBackExternalContactChangeTypeEnum.DEL_FOLLOW_USER.getCode());
            tbWecomExternalContactCustomerFollowUser.setOperUserid(message.getExternalUserId());
            tbWecomExternalContactCustomerFollowUser.setTagIds(StrUtil.EMPTY);
            tbWecomExternalContactCustomerFollowUser.setStatus(WecomCustomerStatusEnum.LOST.getCode());
            tbWecomExternalContactCustomerFollowUser.setLostTime(System.currentTimeMillis());
            tbWecomExternalContactCustomerFollowUserService.updateById(tbWecomExternalContactCustomerFollowUser);
            // 删除标签
            tbWecomExternalContactCustomerFollowUserTagService.remove(Wrappers.lambdaQuery(TbWecomExternalContactCustomerFollowUserTag.class)
                .eq(TbWecomExternalContactCustomerFollowUserTag::getUserId, message.getUserId())
                .eq(TbWecomExternalContactCustomerFollowUserTag::getExternalUserid, message.getExternalUserId())
            );
        }
    }

    @Override
    public void addHalfExternalContact(WxCpXmlMessage message) {
        // 免验证添加成员
        // 配置了客户联系功能的成员被外部联系人删除时
        TbWecomCallbackMsgInfo tbWecomCallbackMsgInfoChageNotice = new TbWecomCallbackMsgInfo();
        tbWecomCallbackMsgInfoChageNotice.setId(IdWorker.getId());
        tbWecomCallbackMsgInfoChageNotice.setAgentId(message.getAgentId());
        tbWecomCallbackMsgInfoChageNotice.setChangeType(message.getChangeType());
        tbWecomCallbackMsgInfoChageNotice.setToUserName(message.getToUserName());
        tbWecomCallbackMsgInfoChageNotice.setFromUserName(message.getFromUserName());
        tbWecomCallbackMsgInfoChageNotice.setMsgCreateTime(message.getCreateTime());
        tbWecomCallbackMsgInfoChageNotice.setMsgType(message.getMsgType());
        tbWecomCallbackMsgInfoChageNotice.setEvent(message.getEvent());
        tbWecomCallbackMsgInfoChageNotice.setUserId(message.getUserId());
        tbWecomCallbackMsgInfoChageNotice.setExternalUserId(message.getExternalUserId());
        tbWecomCallbackMsgInfoChageNotice.setState(StringUtils.isNotEmpty(message.getState()) ? message.getState() : StrUtil.EMPTY);
        tbWecomCallbackMsgInfoChageNotice.setWelcomeCode(StringUtils.isNotEmpty(message.getWelcomeCode()) ? message.getWelcomeCode() : StrUtil.EMPTY);
        tbWecomCallbackMsgInfoChageNotice.setCreateTime(new Date());
        tbWecomCallbackMsgInfoChageNotice.setFullMsg(gson.toJson(message));
        this.save(tbWecomCallbackMsgInfoChageNotice);
    }

    @Override
    public void transferFail(WxCpXmlMessage message) {
        // 企业将客户分配给新的成员接替后，客户添加失败时回调该事件
        TbWecomCallbackMsgInfo tbWecomCallbackMsgInfoChageNotice = new TbWecomCallbackMsgInfo();
        tbWecomCallbackMsgInfoChageNotice.setId(IdWorker.getId());
        tbWecomCallbackMsgInfoChageNotice.setAgentId(message.getAgentId());
        tbWecomCallbackMsgInfoChageNotice.setChangeType(message.getChangeType());
        tbWecomCallbackMsgInfoChageNotice.setToUserName(message.getToUserName());
        tbWecomCallbackMsgInfoChageNotice.setFromUserName(message.getFromUserName());
        tbWecomCallbackMsgInfoChageNotice.setMsgCreateTime(message.getCreateTime());
        tbWecomCallbackMsgInfoChageNotice.setMsgType(message.getMsgType());
        tbWecomCallbackMsgInfoChageNotice.setEvent(message.getEvent());
        tbWecomCallbackMsgInfoChageNotice.setUserId(message.getUserId());
        tbWecomCallbackMsgInfoChageNotice.setExternalUserId(message.getExternalUserId());
        tbWecomCallbackMsgInfoChageNotice.setFailReason(message.getFailReason());
        tbWecomCallbackMsgInfoChageNotice.setCreateTime(new Date());
        tbWecomCallbackMsgInfoChageNotice.setFullMsg(gson.toJson(message));
        this.save(tbWecomCallbackMsgInfoChageNotice);
    }


}
